<?php

declare(strict_types=1);

namespace So\Aspect;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Di\Annotation\Inject;
use So\Annotation\Auth as AuthAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use So\Library\Auth as AuthLibrary;
use So\Request;
use So\Response;

/**
 * 切入Auth注解实现验证
 * @Aspect
 * @author Saopig <1306222220@qq.com>
 */
class Auth extends AbstractAspect
{

    /**
     * @Inject()
     * @var AuthLibrary
     */
    protected $auth;

    /**
     * @Inject()
     * @var ConfigInterface
     */
    protected $config;

    /**
     * @Inject()
     * @var Response
     */
    protected $response;

    /**
     * @Inject()
     * @var Request
     */
    protected $request;

    /**
     * @var string[]
     */
    public $annotations = [
        AuthAnnotation::class,
    ];

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        $Annotation = $proceedingJoinPoint->getAnnotationMetadata();
        $AuthAnnotation = $Annotation->class[AuthAnnotation::class] ?? [];
        $check = $this->auth->check(null, $AuthAnnotation->nocheck ?: [], $AuthAnnotation->nologin ?: []);
        if (!$check) {
            $exception = $this->config->get('so.exception.auth');
            if ($exception) {
                throw new $exception($this->auth->getError());
            }
            return $this->response->error($this->auth->getError());
        }
        return $proceedingJoinPoint->process();
    }
}